home *** CD-ROM | disk | FTP | other *** search
- /* Descriptive Statistics */
-
- options results
- if ~show('P','TCALC') then do
- address command 'run turbocalc:turbocalc'
- address command 'waitforport TCALC'
- loadflag=1
- end
- address 'TCALC'
- 'DEFPUBSCREEN()'
- /* Add-in Rexx Math Library needed for some routines */
- signal on syntax
- if ~show('l','rexxmathlib.library') then
- call addlib('rexxmathlib.library',0,-30)
- if ~show('l','rexxreqtools.library') then
- call addlib('rexxreqtools.library',0,-30)
- if ~show('l','rexxsupport.library') then
- call addlib('rexxsupport.library',0,-30)
- /* add to library list */
- signal off syntax
-
- /* Start Main Routine */
- if loadflag=1 then 'Load()'
- 'ActivateWindow()'
- range=rtgetstring(,"Enter Cell Range for Input","Input Request",,) /* 'rt_pubscrname="TCALC"' */
- colon=pos(":",range)
- if colon=0 then do
- 'Message "Please select a range before executing this script"'
- 'DEFPUBSCREEN "Workbench"'
- exit
- end
-
- /* Find cell references and cell, column numbers */
- start_cell=substr(range,1,colon-1)
- end_cell=substr(range,colon+1)
- start_row=cellrow(start_cell)
- end_row=cellrow(end_cell)
- start_col=cellcol(start_cell)
- end_col=cellcol(end_cell)
- NRows=end_row-start_row+1
- NCols=end_col-start_col+1
-
- /* Get cell reference for output range */
- out_cell=rtgetstring(,"Enter Cell Reference for Output","Input Request",,) /* 'rt_pubscrname="TCALC"' */
- if out_cell="" then do
- 'DEFPUBSCREEN("Workbench")'
- exit
- end
- if length(out_cell)<2 | datatype(left(out_cell,1),'n')=1 then do
- 'Message "Invalid cell reference"'
- 'DEFPUBSCREEN "Workbench"'
- exit
- end
- /* Suppress Screen Redraw to Speed Things Up */
- 'Refresh 0'
-
- /* Open a small output window on tcalc screen*/
- fo=0
- CR='0a'x
- DisplayMsg="Calculating...Please Wait."||CR||"User input is disabled during calculation."||CR
- if open(6Info, 'con:100/0/450/80/Progress/SCREEN TCALC', w) then do
- call writeln(6Info, DisplayMsg)
- fo=1
- end
- else do
- 'Message "TCALC Screen not available for Progress messages"'
- end
- CALL DELAY(150)
-
- /* Get cell references for top cell in each column */
- 'SelectCell' start_cell
- do col=start_col to end_col
- 'GetCursorPos'
- top_cell.col=result
- 'Column 1'
- end
-
- /* Get labels for later use on output */
- 'SelectCell' start_cell
- 'GetValue'
- testlabel=result
- testlabel=strip(testlabel)
- if datatype(testlabel,'n')=1 then do
- labelflag=0
- do x=1 to NCols
- title.x="Column "||x
- end
- end
- else do
- labelflag=1
- NRows=NRows-1
- do x=1 to NCols
- 'GetValue'
- str=result
- title.x=translate(strip(str),"_"," ")
- 'Column 1'
- end
- end
- if fo then call writech(6Info,"Progress...10 ")
- /* Get data from cell range */
- col=start_col
- lav=0
- tot=0
- count.=0
- total.=0
- do x=1 to NCols
- 'SelectCell' top_cell.col
- if labelflag=1 then 'CursorDown 1'
- do y=1 to NRows
- 'GetValue'
- valtest=result
- if datatype(valtest)='NUM' then do
- 'GetValue'
- val=result
- data.x.y=val
- tot=tot+val
- total.x=tot
- count.x=1+count.x
- end
- 'CursorDown 1'
- end
- col=col+1
- tot=0
- lav=0
- val=0
- end
- if fo then call writech(6Info,"20 ")
-
- /* Calculate Means */
- mean.=0
- do x=1 to NCols
- mean.x=total.x/count.x
- end
-
- /* Sort Values */
- call Sort()
-
- /* Calculate Minimum, Maximum and Range */
- min.=0
- max.=0
- valrange.=0
- do z=1 to NCols
- N=count.z
- min.z=data.z.1
- max.z=data.z.N
- val=max.z-min.z
- valrange.z=val
- end
- if fo then call writech(6Info,"30 ")
-
- /* Calculate Median
- median.=0
- item=0
- do x=1 to NCols
- mod=(count.x)//2
- if mod ~=0 then do
- item=((count.x)%2)+1
- median.x=data.x.item
- end
- else do
- item1=(count.x)%2
- item2=item1+1
- median.x=((data.x.item1)+(data.x.item2))/2
- end
- end
- */
- /* Calculate quantiles */
- median.=0
- QA1.=0
- QA3.=0
- q1=0
- Do x=1 to NCols
- mod=count.x//2
- IF mod=0 then DO
- n1=count.x/2
- n2=n1+1
- median.x=(data.x.n1+data.x.n2)/2
- q1=INT(n1/2)+1
- QA1.x=data.x.q1
- q3=n1+q1
- QA3.x=data.x.q3
- END
- ELSE DO
- n3=INT(count.x/2)+1
- median.x=data.x.n3
- q1=INT(n3/2)
- q1=q1+0
- q2=q1+1
- QA1.x=((data.x.q1)+(data.x.q2))/2
- q3=n3+q1
- q4=q3+1
- QA3.x=((data.x.q3)+(data.x.q4))/2
- END
- END
- if fo then call writech(6Info,"40 ")
-
- /* Calculate Mode */
- flag.=0
- z=0
- /* First create parallel set of data */
- cnt.=0
- do x=1 to NCols
- t=1
- temp.x.1=data.x.1
- cnt.x=1
- do y=2 to count.x
- z=y-1
- if (data.x.y)~=(data.x.z) then do
- cnt.x=1+cnt.x
- t=t+1
- temp.x.t=data.x.y
- end
- end
- end
- z=0
- maxnum.=0 /* array to hold an index of the numbers that are repeated */
- modecount.=0
- do x=1 to NCols
- do i=1 to cnt.x
- do y=1 to count.x
- if temp.x.i=data.x.y then maxnum.x.i=1+maxnum.x.i
- end
- if (maxnum.x.i)>1 then modecount.x=1+modecount.x
- end
- end
- mode.=0 /* mode array */
- do x=1 to NCols
- select
- when modecount.x=1 then do
- dummy1=0
- dummy2=0
- dump1=0
- dump2=0
- do y=1 to count.x
- dummy1=data.x.y
- dummy2=maxnum.x.y
- z=y+1
- if z<=count.x & dummy2>maxnum.x.z then do
- dump1=data.x.z
- dump2=maxnum.x.z
- data.x.z=dummy1
- maxnum.x.z=dummy2
- data.x.y=dump1
- maxnum.x.y=dump2
- end
- z=0
- end
- NR=count.x
- mode.x=data.x.NR
- end
- when modecount.x=0 then
- mode.x="None"
- otherwise
- mode.x="Multi_(See_Below)"
- end
- end
- if fo then call writech(6Info,"50 ")
-
- /* Calculate Standard deviation and Variance */
- dat=0
- meenx=0
- sum.=0 /* Array holding sum of x minus mean of x squared */
- sum3.=0 /* Array holding sum of x minus mean of x to the 3rd power */
- sum4.=0 /* Array holdong sum of x minus mean of x to the 4th power */
- sd.=0 /* Standard deviation array */
- var.=0 /* Variance array */
- m2.=0
- m3.=0
- m4.=0
- do x=1 to NCols
- sum.x=0
- sum3.x=0
- sum4.x=0
- meenx=mean.x
- do y =1 to count.x
- dat=data.x.y
- sum.x=(dat-meenx)**2+(sum.x)
- sum3.x=(dat-meenx)**3+(sum3.x)
- sum4.x=(dat-meenx)**4+(sum4.x)
- end
- N=(count.x)-1
- var.x=(sum.x)/N
- sd.x=sqrt(var.x)
- m2.x=(sum.x)/(count.x) /* 2nd moment about the mean */
- m3.x=(sum3.x)/(count.x) /* 3rd moment about the mean */
- m4.x=(sum4.x)/(count.x) /* 4th moment about the mean */
- end
- if fo then call writech(6Info,"60 ")
-
- /* Calculate standard error of the mean */
- serr.=0 /* Standard error array */
- do x=1 to NCols
- val=sqrt(count.x)
- serr.x=(sd.x)/(val)
- end
- if fo then call writech(6Info,"70 ")
-
- /* Calculate Skewness and Kurtosis */
- sk.=0 /* Skewness array */
- ku.=0 /* Kurtosis array */
- mval=0
- do x=1 to NCols
- mval=(m2.x)*sqrt(m2.x)
- sk.x=(m3.x)/mval
- ku.x=(m4.x)/((m2.x)**2)-3
- end
- if fo then call writech(6Info,"80 ")
-
- /* Calculate Confidence Levels */
- clow.=0 /* low 95% confidence level array */
- cup.=0 /* high 95% confidence level array */
- clow2.=0 /* low 99% confidence level array */
- cup2.=0 /* high 99% confidence level array */
- do x=1 to NCols
- clow.x=(mean.x)-(1.96*serr.x)
- cup.x=(mean.x)+(1.96*serr.x)
- clow2.x=(mean.x)-(2.58*serr.x)
- cup2.x=(mean.x)+(2.58*serr.x)
- end
- if fo then call writech(6Info,"90 ")
-
- /* Calculate Geometric mean, Harmonic mean, Root Mean Square, Mean Deviation */
- calcrms.=0
- calcg.=0
- calch.=0
- logg.=0
- G.=0
- H.=0
- RMS.=0
- calcmd.=0
- MD.=0
- Do x=1 to NCols
- Do y=1 to count.x
- calcg.x=(calcg.x)+(log10(data.x.y))
- calch.x=(calch.x)+(1/data.x.y)
- calcrms.x=(calcrms.x)+(data.x.y)**2
- calcmd.x=(calcmd.x)+abs((data.x.y)-(mean.x))
- end
- logg.x=(calcg.x)/(count.x)
- 'SelectCell' out_cell
- 'Put' logg.x
- 'CursorDown 1'
- 'Put "=POW10(Cell(-1;0))"'
- 'GetValue'
- G.x=result
- G.x=trunc(G.x,4)
- H.x=(count.x)/(calch.x)
- RMS.x=SQRT((calcrms.x)/(count.x))
- MD.x=(calcmd.x)/(count.x)
- calcmd.x=(calcmd.x)/(count.x)
- end
- if fo then do
- call writeln(6Info,"100 ")
- call writeln(6Info,"Writing output to window...")
- end
- /* Output */
- 'SelectCell' out_cell
- 'ColumnWidth 25'
- 'Put' "Statistics"
- 'Column 1'
- do x=1 to NCols
- 'GetCursorPos'
- first_cell.x=result
- 'Column 1'
- end
- 'SelectCell' out_cell
- 'CursorDown 1'
- 'Put' "Count:"
- 'CursorDown 1'
- 'Put' "Sum:"
- 'CursorDown 1'
- 'Put' "Mean(Arith.):"
- 'CursorDown 1'
- 'Put' "Mean(Geo.):"
- 'CursorDown 1'
- 'Put' "Mean(Harm.):"
- 'CursorDown 1'
- 'Put' "Mean(Quad.):"
- 'CursorDown 1'
- 'Put' "Mode:"
- 'CursorDown 1'
- 'Put "First Quartile:"'
- 'CursorDown 1'
- 'Put' "Median:"
- 'CursorDown 1'
- 'Put "Third Quartile:"'
- 'CursorDown 1'
- 'Put' "Range:"
- 'CursorDown 1'
- 'Put' "Maximum:"
- 'CursorDown 1'
- 'Put' "Minimum:"
- 'CursorDown 1'
- 'Put "Std. Error:"'
- 'CursorDown 1'
- 'Put "Std. Deviation:"'
- 'CursorDown 1'
- 'Put "Mean Deviation:"'
- 'CursorDown 1'
- 'Put' "Variance:"
- 'CursorDown 1'
- 'Put' "Skewness:"
- 'CursorDown 1'
- 'Put' "Kurtosis:"
- 'CursorDown 1'
- 'Put "Confidence Level (95%)-low:"'
- 'CursorDown 1'
- 'Put "Confidence Level (95%)-high:"'
- 'CursorDown 1'
- 'Put "Confidence Level (99%)-low:"'
- 'CursorDown 1'
- 'Put "Confidence Level (99%)-high:"'
- do x=1 to NCols
- 'SelectCell' first_cell.x
- j=x-1
- if (x>1) & (modecount.j>1) then 'Column 1'
- 'ColumnWidth' 10
- title=""""||title.x||""""
- 'Alignment 2'
- 'Put' title
- 'CursorDown 1'
- 'Put' count.x
- 'CursorDown 1'
- 'Put' total.x
- 'CursorDown 1'
- 'Put' format(mean.x,,4)
- 'CursorDown 1'
- 'Put' format(G.x,,4)
- 'CursorDown 1'
- 'Put' format(H.x,,4)
- 'CursorDown 1'
- 'Put' format(RMS.x,,4)
- 'CursorDown 1'
- 'Put' mode.x
- 'CursorDown 1'
- 'Put' QA1.x
- 'CursorDown 1'
- 'Put' median.x
- 'CursorDown 1'
- 'Put' QA3.x
- 'CursorDown 1'
- 'Put' valrange.x
- 'CursorDown 1'
- 'Put' max.x
- 'CursorDown 1'
- 'Put' min.x
- 'CursorDown 1'
- 'Put' format(serr.x,,4)
- 'CursorDown 1'
- 'Put' format(sd.x,,4)
- 'CursorDown 1'
- 'Put' format(MD.x,,4)
- 'CursorDown 1'
- 'Put' format(var.x,,4)
- 'CursorDown 1'
- 'Put' format(sk.x,,4)
- 'CursorDown 1'
- 'Put' format(ku.x,,4)
- 'CursorDown 1'
- 'Put' format(clow.x,,4)
- 'CursorDown 1'
- 'Put' format(cup.x,,4)
- 'CursorDown 1'
- 'Put' format(clow2.x,,4)
- 'CursorDown 1'
- 'Put' format(cup2.x,,4)
- if modecount.x>1 then do
- 'CursorDown 1'
- 'Alignment 2'
- 'Put "Mode"'
- 'Column 1'
- 'Alignment 2'
- 'ColumnWidth 7'
- 'Put "Count"'
- 'Column -1'
- 'CursorDown 1'
- do i=1 to cnt.x
- if maxnum.x.i>1 then do
- 'Put' temp.x.i
- 'Column 1'
- 'Put' maxnum.x.i
- 'Column -1'
- 'CursorDown 1'
- end
- end
- end
- end
-
- 'Refresh 1'
- 'Refresh 2'
- /*'Message' "Finished"*/
- /*indicate the main script is finished*/
- DisplayMsg="Cleaning up ...."||CR||"Exiting"
- result=writeln(6Info, DisplayMsg)
- if result~=0 then do
- /*Wait 3 seconds*/
- CALL DELAY(150)
- /* close window*/
- result=close(6Info)
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- /* Procedures */
-
- cellrow: procedure
- do
- parse arg cell
- do charpos=2 to length(cell)
- if datatype(substr(cell,charpos,1),n) then return substr(cell,charpos)
- end
- return 0
- end
- Return
-
- cellcol: procedure
- do
- parse arg cell
- labels="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- cell=upper(cell)
- len=length(cell)
- val=0
- do charpos=1 to len
- if datatype(substr(cell,charpos,1),n) then
- do cell=reverse(substr(cell,1,charpos-1))
- do x=1 to length(cell)
- val=(26**(x-1))*pos(substr(cell,x,1),labels)+val
- end
- return val
- end
- end
- return 0
- end
- Return
- /* It is important to put the exposed array at the end of the next line */
- Sort: procedure expose NCols count. data.
- do x=1 to NCols
- L=(xtoy(2,int(log(count.x)/log(2))))-1
- Do Until L<1
- L=trunc(int(L/2))
- Do J=1 to L
- Do K=J+L To count.x By L
- I=K
- dumdat=data.x.I
- Do while I>L
- y=I-L
- If data.x.y ~> dumdat then Leave
- data.x.I=data.x.y
- I=I-L
- End
- data.x.I=dumdat
- End
- End
- End
- End
- Return
-
- syntax:
- if arg(1)='FAIL' then do
- 'Message "Library is unavailable."'
- 'DEFPUBSCREEN "Workbench"'
- exit
- end
- 'DEFPUBSCREEN("Workbench")'
- exit
-
- Format: procedure
-
- arg number, before, after
- CallLine = SIGL
- if ~datatype(CallLine, 'N') then CallLine = '??'
-
- /* Make sure we have a number as first (required) argument */
- if ~datatype(number, 'N') then do
- if number = '' then
- fc = 17 /* Wrong number of arguments */
- else
- fc = 47 /* Arithmetic conversion error */
- signal FormatSyntaxError
- end
- num = number + 0
- if before = '' & after = '' then
- return num
- else do
- parse var num integer '.' fraction
- if before = '' then before = length(integer)
- if after = '' then after = length(fraction)
- if ~datatype(before, N) | ~datatype(after, N) then
- do fc = 18
- signal FormatSyntaxError
- end
- if before < length(integer) then do
- fc = 18
- signal FormatSyntaxError
- end
- if after ~= length(fraction) then do
- fraction = trunc(('.'fraction'0') + ('.'copies('0', after)'5'), after)
- if integer<1&integer>-1 then integer=integer
- else integer = integer + (fraction % 1)
- fraction = substr(fraction, 3)
- end
- if fraction >= 0 then
- return right(integer, before)'.'fraction
- else
- return right(integer, before)
- end
-
- FormatSyntaxError:
- if show('F', STDERR) then
- call writeln(STDERR, '+++ Error' fc 'in line' CallLine':' errortext(fc))
- else
- mess='+++ Error' fc 'in line' CallLine':' errortext(fc)
- 'Message' mess
- parse source Func .
- if Func = 'FUNCTION' then do
- 'DEFPUBSCREEN("Workbench")'
- exit "Err"
- end
- else do
- 'DEFPUBSCREEN("Workbench")'
- exit 10
- end
-